// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// t [author] rhyme_lph
// I [email]  rhymelph@gmail.com
// Q [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/account_entity.dart';
import 'package:finance_app/src/entities/setting_data_entity.dart';
import 'package:finance_app/src/http_service/http_account_service.dart';
import 'package:finance_app/src/provider/dashboard/bank/cash_and_bank_provider.dart';
import 'package:finance_app/src/provider/dashboard/bank/new_account_transfer_provider.dart';
import 'package:finance_app/src/provider/dashboard/cash_in/new_cash_in_provider.dart';
import 'package:finance_app/src/provider/dashboard/cash_out/new_cash_out_provider.dart';
import 'package:finance_app/src/provider/dashboard/expense/new_expense_provider.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/widgets/bottom_sheet/calendar_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/currency_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/got_it_tip_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/title_got_it_tip_bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'package:finance_app/src/page/dashboard/bank/add_bank_account_page.dart';

class AddBankAccountProvider extends BaseProvider {
  TextEditingController bankNameController = TextEditingController();
  FocusNode bankNameFocusNode = FocusNode();

  TextEditingController bankAccountNumberController = TextEditingController();
  FocusNode bankAccountNumberFocusNode = FocusNode();

  TextEditingController openingBalanceController = TextEditingController();
  FocusNode openingBalanceFocusNode = FocusNode();

  SettingDataCurrency selectCurrency;

  DateTime asAt;

  bool isEnableAsAt = true;

  bool hasUsed = false;

  @override
  void dispose() {
    super.dispose();
    bankNameController.dispose();
    bankNameFocusNode.dispose();
    bankAccountNumberController.dispose();
    bankAccountNumberFocusNode.dispose();
    openingBalanceController.dispose();
    openingBalanceFocusNode.dispose();
  }

  @override
  void initState() {
    super.initState();
    final ex = Providers.get<NewExpenseProvider>(
        RouterGenProviders.newExpensePage, null);
    if (ex != null) {
      asAt = ex.date;
      isEnableAsAt = false;
    }
    print(ex);
    final cashOut = Providers.get<NewCashOutProvider>(
        RouterGenProviders.newCashOutPage, null);
    if (cashOut != null) {
      asAt = cashOut.date;
      isEnableAsAt = false;
    }
    print(cashOut);
    final cashIn = Providers.get<NewCashInProvider>(
        RouterGenProviders.newCashInPage, null);
    if (cashIn != null) {
      asAt = cashIn.date;
      isEnableAsAt = false;
    }
    print(cashIn);
    final transfer = Providers.get<NewAccountTransferProvider>(
        RouterGenProviders.newAccountTransferPage, null);
    if (transfer != null) {
      asAt = transfer.date;
      isEnableAsAt = false;
    }
    print(transfer);
    if (cashIn == null &&
        cashOut == null &&
        ex == null &&
        transfer == null &&
        id == null) {
      asAt = DateTime.tryParse(Config.currentFY.startDate);
      isEnableAsAt = true;
    }
  }

  @override
  Future get dataFuture => null;

  void unFocus() {
    bankNameFocusNode.unfocus();
    bankAccountNumberFocusNode.unfocus();
    openingBalanceFocusNode.unfocus();
  }

  void onChangeCurrency() {
    unFocus();
    obtainContext?.call((context) async {
      selectCurrency = await showCurrencyBottomSheet(context, selectCurrency);
      update();
    });
  }

  void onAdd() async {
    unFocus();

    String accountNumber = bankAccountNumberController.text;
    String bankName = bankNameController.text;
    String openingBalance = openingBalanceController.text;

    num balance = num.parse(openingBalance, (s) => null);
    if (balance == null) {
      showToast(S.current.please_enter_the_right_balance);
      return;
    }
    AccountEntity entity;
    if (id == null) {
      await post(
          HttpAccountService.accountCreate(
            accountNumber,
            bankName,
            selectCurrency.key,
            balance,
            asAt,
          ),
          autoHandler: AutoHandler.Toast,
          loadingTip: S.current.loading, onSuccess: (result) {
        entity = getEntityFromResult<AccountEntity>(result);
      });
    } else {
      await post(
          HttpAccountService.accountUpdate(
            id,
            accountNumber,
            bankName,
            selectCurrency.key,
            balance,
            asAt,
          ),
          autoHandler: AutoHandler.Toast,
          loadingTip: S.current.loading, onSuccess: (result) {
        entity = getEntityFromResult<AccountEntity>(result);
      });
    }
    if (entity != null) {
      Providers.get<CashAndBankProvider>(
              RouterGenProviders.cashAndBankPage, null)
          ?.loadAccount();
      obtainContext?.call((context) {
        Navigator.of(context).pop(entity);
      });
    }
  }

  void onChangeAsAt() {
    unFocus();
    obtainContext?.call((context) async {
      asAt = await showCalendarBottomSheet(context, asAt);
      update();
    });
  }

  void onShowAsOnDateTip() {
    unFocus();
    obtainContext?.call((context) {
      FocusScope.of(context).requestFocus(FocusNode());
      showAsOnDateBottomSheet(context);
    });
  }

  int id;

  void initAccount(AccountEntity data) {
    if (data == null) {
      selectCurrency = Config.defaultCurrency;
      return;
    }
    id = data.id;
    hasUsed = data.hasUsed;
    bankNameController.text = data.bankName;
    bankAccountNumberController.text = data.accountNumber;
    selectCurrency = Config.settingData.currency.firstWhere(
        (element) => element.key == data.currencyCode,
        orElse: () => null);
    openingBalanceController.text = data.balance.toString();
    asAt = DateTimeUtils.toDateTime(data.asAt, 'yyyy-MM-dd HH:mm:ss');
    isEnableAsAt = false;
  }
}
